package com.niiwoo.civet.user.service.duboo;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.snapdata.dto.request.JdDetailSaveReqDTO;
import com.niiwoo.civet.snapdata.dto.request.JdSaveReqDTO;
import com.niiwoo.civet.snapdata.service.JdDubboService;
import com.niiwoo.civet.user.dto.request.UserAuthorizationInfoDTO;
import com.niiwoo.civet.user.enums.UserDataTypeEnum;
import com.niiwoo.civet.user.service.UserAuthJdDubboService;
import com.niiwoo.civet.user.service.local.UserAuthCommonTemplateService;
import com.niiwoo.civet.user.service.local.UserAuthorizationInfoService;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.tiancheng.component.TianchengAuthJdService;
import com.niiwoo.tripod.tiancheng.component.TianchengAuthService;
import com.niiwoo.tripod.tiancheng.request.auth.EducationDataQueryRequest;
import com.niiwoo.tripod.tiancheng.request.auth.JdDataQueryRequest;
import com.niiwoo.tripod.tiancheng.response.auth.EducationDataQueryResponse;
import com.niiwoo.tripod.tiancheng.response.auth.JdDataQueryResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author DELL
 * @create 2018-04-17 17:19
 * @desc 京东授权Dubbo实现类
 **/
@Slf4j
@Service(version = "1.0.0")
public class UserAuthJdDubboServiceImpl extends UserAuthCommonTemplateService implements UserAuthJdDubboService {

    @Autowired
    TianchengAuthJdService tianchengAuthJdService;

    @Reference(version = "1.0.0")
    JdDubboService jdDubboService;

    @Autowired
    private UserAuthorizationInfoService userAuthorizationInfoService;

    /**
     * 上次授权失败原因显示结果页面
     */
    private final String h5ErrorMsgUrl = "{0}/html5/project/creditresult/index.html#/authorizeFail_jd?t={1}&msg={2}";

    /**
     * 天秤授权同步get回调h5页面地址
     */
    private final String h5CallbackResultUrl = "/html5/project/creditresult/index.html#/index_jd";

    /**
     * 天秤授权数据回调url
     */
    private final String dataCallbackUrl="/tc/authJdData/callback";

    @Override
    public String getH5ErrorMsgUrl() {
        return h5ErrorMsgUrl;
    }

    @Override
    public String getH5CallbackResultUrl() {
        return h5CallbackResultUrl;
    }

    @Override
    public String getDataCallbackUrl() {
        return dataCallbackUrl;
    }

    @Override
    public String getAuthBizName() {
        return "JdAuth";
    }

    @Override
    public String getAuthChineseName() {
        return "京东";
    }

    @Override
    public UserDataTypeEnum getDataType() {
        return UserDataTypeEnum.JD_AUTHORIZE;
    }

    @Override
    public void saveDataCallback(String userId, String jsonString) {
        log.info("开始京东数据拉取userId={}, jdLoginName={}", userId, jsonString);
        //解析jsonString中的数据
        String jdLoginName = jsonString;

        //存储loginname到数据库表
        userAuthorizationInfoService.saveJdInfo(userId, jsonString);

        try {
            queryAndSaveData(userId, jdLoginName);
        }catch (Exception e){
            log.error("拉取解析保存京东信息出现异常", e);
        }
    }

    @Override
    public TianchengAuthService getTianchengAuthService() {
        return tianchengAuthJdService;
    }

    @Override
    public boolean refreshData(String userId) {
        return queryAndSaveData(userId, null);
    }

    public boolean queryAndSaveData(String userId, String jdLoginName) {
        JdDataQueryRequest request = new JdDataQueryRequest();
        if(StringUtils.isBlank(jdLoginName)){
            UserAuthorizationInfoDTO userAuthorizationInfoDTO = userAuthorizationInfoService.selectByUserId(userId);
            if(userAuthorizationInfoDTO != null){
                jdLoginName = userAuthorizationInfoDTO.getJdLoginName();
            }
        }
        request.setLoginname(jdLoginName);
        CompletableFuture<JdDataQueryResponse> jdDataQueryResponseCompletableFuture = tianchengAuthJdService.dataQuery(request);
        try {
            int timeout = 20;
            JdDataQueryResponse response = jdDataQueryResponseCompletableFuture.get(timeout, TimeUnit.SECONDS);
            log.info("userId={},京东信息查询天秤返回结果：{}", userId, JSON.toJSONString(response));
            if (response == null) {
                log.info(userId + "查询京东数据天秤返回空");
                throw new BizException("USR19111");
            }
            if(StringUtils.isBlank(response.getResult())){
                log.info(userId + "查询京东数据天秤返回空");
                throw new BizException("USR19111");
            }
            JSONObject jsonObject = null;
            try {
                String result = StringUtils.replace(response.getResult(),"\\","");
                jsonObject = JSONObject.parseObject(result);
            }catch (Exception e){
                log.error(userId + "京东信息解析失败:"+response.getResult(), e);
                throw new BizException("USR19113");
            }

            //基本信息
            JSONObject jdUserInfoJson = jsonObject.getJSONObject("jdUserInfo");

            //白条信息
            JSONObject jdLousInfoJson=jsonObject.getJSONObject("jdIous");

            //消费记录
            JSONArray consumptionAmounts = jsonObject.getJSONArray("jdOrders");

            List<JdDetailSaveReqDTO>  list = new ArrayList<>();
            BigDecimal totalConsumptionAmount = BigDecimal.ZERO;
            if(consumptionAmounts != null) {
                for (int i = 0; i < consumptionAmounts.size(); i++) {
                    JSONObject consumptionAmount = consumptionAmounts.getJSONObject(i);
                    if(consumptionAmount == null){
                        continue;
                    }
                    JdDetailSaveReqDTO dto = new JdDetailSaveReqDTO();
                    dto.setConsumeTime(coverToDate(consumptionAmount.getLong("payTime")));
                    dto.setConsumeAmount(coverBigDecimal(consumptionAmount.getString("money")));
                    list.add(dto);
                    totalConsumptionAmount = totalConsumptionAmount.add(dto.getConsumeAmount());
                }
            }

            JdSaveReqDTO jdSaveReqDTO = new JdSaveReqDTO();
            jdSaveReqDTO.setUserId(userId);

            if(jdUserInfoJson!= null){
                jdSaveReqDTO.setMobileNo(jdUserInfoJson.getString("mobile"));
                jdSaveReqDTO.setRealName(jdUserInfoJson.getString("name"));
            }

            if(jdLousInfoJson != null){
                jdSaveReqDTO.setWhiteScore(coverBigDecimal(jdLousInfoJson.getString("credit")));
                jdSaveReqDTO.setCreditAmount(coverBigDecimal(jdLousInfoJson.getString("loanQuota")));
                jdSaveReqDTO.setScoreLevel(jdLousInfoJson.getString("level"));
            }

            jdSaveReqDTO.setConsumeTotal(totalConsumptionAmount);


            jdSaveReqDTO.setJdDetailList(list);

            log.debug("测试："+ JSON.toJSONString(jdSaveReqDTO));
            Integer saveResult = jdDubboService.saveJdInfo(jdSaveReqDTO);
            log.info("保存用户学历信息到快照数据库返回结果userId={}, result={}", userId, saveResult);
            if(saveResult != null && saveResult>0){
                return true;
            }else {
                throw new BizException("USR19114");
            }
        } catch (Throwable e) {
            log.error("保存京东信息出现异常", e);
        }
        return false;
    }

    /**
     * 金额null处理,及分转换成元
     * @param numberString
     * @return
     */
    private BigDecimal coverBigDecimal(String numberString) {
        if (StringUtils.isBlank(numberString)) {
            return BigDecimal.ZERO;
        }
        try {
            BigDecimal number = new BigDecimal(numberString);
            return number;
        }catch (Throwable e){
            log.error("coverBigDecimal方法异常："+numberString+"转换为BigDecimal失败!", e);
            return BigDecimal.ZERO;
        }
    }

    private Date coverToDate(Long millions){

        if(millions == null){
            return null;
        }
        Calendar c=Calendar.getInstance();
        c.setTimeInMillis(millions);

        return c.getTime();
    }
}
